package handler

import (
	"../model"
	"../utils"
	"encoding/json"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"net/http"
	"strconv"
	"io/ioutil"
)

const DEFAULT_PAGESIZE  uint64 = 10



func SaveUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var u model.User
	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()
	json.Unmarshal([]byte(result), &u)

	var err error
	var resq []byte
	response := Response{}.Default()
	if u,err = u.Save(); err != nil {
		response.Status = http.StatusForbidden
		response.Code = StatusUnauthorized
		response.Message = err.Error()
	} else {
		response.Body["user"] = u
	}

	resq, err = json.Marshal(response)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	w.Write(resq)
}

func DeleteUsers(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	type parseModel struct {
		IDS []uint64 `json:"ids"`
	}
	var m parseModel

	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()

	json.Unmarshal([]byte(result), &m)

	user := model.User{}

	response := Response{}.Default()

	if err := user.Remove(m.IDS); err != nil {
		response.Code = StatusNotAcceptable
		response.Message = err.Error()
	}

	b, err := json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}

func UpdateUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	var u model.User
	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()
	json.Unmarshal([]byte(result), &u)

	var err error
	var resq []byte
	response := Response{}.Default()

	if u,err = u.Save(); err != nil {
		response.Code = StatusNotAcceptable
		response.Message = err.Error()
	} else {
		response.Body["user"] = u
		resq, err = json.Marshal(response)
	}
	if err != nil {
		return
	}
	w.Write(resq)
}

func GetUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	var err error
	var b []byte

	response := Response{}.Default()
	id, _ := strconv.ParseUint(ps.ByName("id"), 10, 64)
	if ( id == 0 ) {
		response.Code = StatusNotAcceptable
		response.Message = "cannot log in "
	}else {
		user := model.User{ID: id}
		response.Body["user"] = user.Get()
	}

	b, err = json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)

}

func GetCurrentUser(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	var err error
	var b []byte

	response := Response{}.Default()
	userid := utils.GetUserInfoFromContext(r.Context())

	user := model.User{ID: userid}
	response.Body["user"] = user.Get()

	b, err = json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}
func GetUsers(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	var err error
	var b []byte
	var filter_by string
	var filter_id uint64
	if len(r.Form["filter_by"]) > 0 {
		filter_by = r.Form["filter_by"][0]
	}
	if len(r.Form["filter_id"])>0 {
		filter_id,_ = strconv.ParseUint(r.Form["filter_id"][0], 10, 64)
	}
	response := Response{}.Default()

	query := parseQuery(r)

	if ( filter_by == "group") {
		response.Body["users"],response.Body["total"] = model.User{}.GetAll(r.Form["fields"],query.Page, query.PageSize,filter_by,filter_id)
	}else if ( filter_by == "tag") {
		response.Body["users"],response.Body["total"] = model.User{}.GetAll(r.Form["fields"],query.Page, query.PageSize,filter_by,filter_id)
	}else {
		response.Body["users"],response.Body["total"] = model.User{}.GetAll(r.Form["fields"],query.Page, query.PageSize,"",0)
	}

	b, err = json.Marshal(response)

	if err != nil {
		fmt.Printf("errors :", err)
	}

	w.Write(b)
}


func GetTags(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	query := parseQuery(r)
	var err error
	var b []byte

	response := Response{}.Default()
	response.Body["tags"],response.Body["total"] = model.Tag{}.GetAll(query.Page, query.PageSize)
	b, err = json.Marshal(response)

	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}

func SaveTag(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	type parseModel struct {
		ID   uint64   `json:id`
		Name  string  `json:"name"`
		Users  []uint64 `json:"users`
	}
	var m parseModel
	var err error

	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()
	json.Unmarshal([]byte(result), &m)

	tag := model.Tag{ID:m.ID,Name:m.Name}

	response := Response{}.Default()
	if tag,err = tag.Save(m.Users); err != nil {
		response.Code = StatusNotAcceptable
		response.Message = err.Error()
	}else {
		response.Body["tag"] = tag
	}

	b, err := json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}

func DeleteTags(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	type parseModel struct {
		IDS []uint64 `json:"ids"`
	}
	var m parseModel

	result, _ := ioutil.ReadAll(r.Body)
	r.Body.Close()

	json.Unmarshal([]byte(result), &m)

	tag := model.Tag{}

	response := Response{}.Default()

	if err := tag.Remove(m.IDS); err != nil {
		response.Code = StatusNotAcceptable
		response.Message = err.Error()
	}

	b, err := json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}
func GetTag(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	r.ParseForm()
	var err error
	var b []byte

	response := Response{}.Default()
	id, _ := strconv.ParseUint(ps.ByName("id"), 10, 64)
	with_users, err := strconv.ParseBool( r.Form["with_users"][0])
	tag := model.Tag{ID: id}
	response.Body["tag"] = tag.Get(with_users)
	b, err = json.Marshal(response)
	if err != nil {
		fmt.Printf("errors :", err)
	}
	w.Write(b)
}
